<template>
  <div v-if="readonly" class="itemNames">
    <span v-for="i in names" :key="i">{{ i }}</span>
  </div>
  <el-select
    v-else-if="mode == 'select'"
    v-model="inputVal"
    :disabled="disabled"
    :placeholder="place"
    :style="styleSet"
    :clearable="clearable"
    :class="className"
    :multiple="multiple"
    @change="chooseChange"
  >
    <el-option
      v-for="item in items"
      :key="item.DicValue"
      :label="item.DicText"
      :value="item.DicValue"
    />
  </el-select>
  <el-checkbox-group
    v-else-if="mode == 'checkbox' && multiple"
    v-model="inputVal"
    :disabled="disabled"
    @change="chooseChange"
  >
    <el-checkbox v-for="item in items" :key="item.DicValue" :label="item.DicValue">{{
      item.DicText
    }}</el-checkbox>
  </el-checkbox-group>
  <el-checkbox-group
    v-else-if="mode == 'checkbox' && multiple == false"
    v-model="inputVal"
    :disabled="disabled"
    :max="1"
    @change="chooseChange"
  >
    <el-checkbox v-for="item in items" :key="item.DicValue" :label="item.DicValue">{{
      item.DicText
    }}</el-checkbox>
  </el-checkbox-group>
  <el-checkbox-group
    v-else-if="mode == 'button' && multiple"
    v-model="inputVal"
    :disabled="disabled"
    @change="chooseChange"
  >
    <el-checkbox-button v-for="item in items" :key="item.DicValue" :label="item.DicValue">{{
      item.DicText
    }}</el-checkbox-button>
  </el-checkbox-group>
  <el-radio-group
    v-else-if="mode == 'radio'"
    v-model="inputVal"
    :disabled="disabled"
    @input="chooseChange"
  >
    <el-radio v-for="item in items" :key="item.DicValue" :label="item.DicValue">{{
      item.DicText
    }}</el-radio>
  </el-radio-group>
  <el-radio-group
    v-else
    v-model="inputVal"
    :disabled="disabled"
    @input="chooseChange"
  >
    <el-radio-button
      v-for="item in items"
      :key="item.DicValue"
      :label="item.DicValue"
    >{{ item.DicText }}</el-radio-button>
  </el-radio-group>
</template>

<script>
import { gets, GetDicTextList } from '@/api/base/dictItem'
export default {
  props: {
    dicId: {
      type: String,
      default: null
    },
    clearable: {
      type: Boolean,
      default: true
    },
    disabled: {
      type: Boolean,
      default: false
    },
    className: {
      type: String,
      default: 'el-input'
    },
    label: {
      type: String,
      default: null
    },
    value: {
      default: null
    },
    placeholder: {
      type: String,
      default: '选择字典'
    },
    filterFunc: {
      type: Function,
      default: null
    },
    mode: {
      type: String,
      default: 'select'
    },
    multiple: {
      type: Boolean,
      default: false
    },
    styleSet: {
      type: Object,
      default: null
    },
    readonly: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      place: null,
      items: [],
      names: [],
      inputVal: null
    }
  },
  watch: {
    dicId: {
      handler(val) {
        if (val) {
          this.reset()
        }
      },
      immediate: true
    },
    value: {
      handler(val) {
        this.resetValue(val)
        if (this.readonly) {
          this.reset()
        } else if (this.items.length > 0) {
          this.loadLabel()
        }
      },
      immediate: false
    },
    placeholder: {
      handler(val) {
        this.place = val
      },
      immediate: true
    },
    multiple: {
      handler(val) {
        if (val && this.value != null && Array.isArray(this.value) && this.value.length > 1) {
          this.resetValue(null)
        } else {
          this.resetValue(this.value)
        }
      },
      immediate: false
    },
    mode: {
      handler(val) {
        this.resetValue(this.value)
      },
      immediate: false
    }
  },
  mounted() {},
  methods: {
    resetValue(val) {
      if (val == null) {
        this.inputVal = this.multiple || (this.mode === 'button' && this.multiple) || this.mode === 'checkbox' ? [] : null
      } else if (this.multiple || (this.mode === 'button' && this.multiple) || this.mode === 'checkbox') {
        this.inputVal = Array.isArray(val) ? val : [val]
      } else if (Array.isArray(val)) {
        this.inputVal = val.length > 0 ? val[0] : null
      } else {
        this.inputVal = val
      }
    },
    reset() {
      this.resetValue(this.value)
      if (this.readonly) {
        if (this.inputVal == null || this.inputVal.length === 0) {
          this.names = []
        } else if (Array.isArray(this.inputVal)) {
          this.loadItemText(this.inputVal)
        } else {
          this.loadItemText([this.inputVal])
        }
      } else {
        this.loadDict()
      }
    },
    async loadDict() {
      const res = await gets(this.dicId)
      if (this.filterFunc) {
        this.items = this.filterFunc(res)
      } else {
        this.items = res
      }
      this.loadLabel()
    },
    loadLabel() {
      let label = null
      if (this.inputVal != null && this.inputVal.length !== 0) {
        if (Array.isArray(this.inputVal)) {
          label = this.formatText(this.inputVal)
        } else {
          const item = this.items.find((c) => c.DicValue === this.inputVal)
          label = item.DicText
        }
      }
      this.$emit('update:label', label)
    },
    formatText(value) {
      let text = ''
      this.items.forEach(c => {
        if (value.includes(c.DicValue)) {
          text = text + ',' + c.DicText
        }
      })
      return text.substring(1)
    },
    async loadItemText(ids) {
      this.names = await GetDicTextList(this.dicId, ids)
      if (this.multiple) {
        this.$emit('update:label', this.names.join(','))
      } else {
        this.$emit('update:label', this.names[0])
      }
    },
    chooseChange(value) {
      this.inputVal = value
      let item = null
      let label = null
      let val = null
      if (value != null && value.length !== 0) {
        if (Array.isArray(value)) {
          item = this.items.filter((c) => value.includes(c.DicValue))
          label = this.formatText(value)
          val = this.multiple ? value : value[0]
        } else {
          item = this.items.find((c) => c.DicValue === value)
          label = item.DicText
          val = this.multiple ? [value] : value
        }
      }
      this.$emit('update:label', label)
      this.$emit('input', val)
      this.$emit('change', val, item)
    }
  }
}
</script>

<style scoped>
.itemNames {
  display: inline-block;
  line-height: 20px;
}
.itemNames span{
  padding: 5px;
}
.el-radio-button {
  margin-bottom: 5px;
}
.el-checkbox-button {
  margin-bottom: 5px;
}
</style>
